﻿package com.hutra.utils {
	
	import flash.net.URLRequest;
	import flash.net.URLLoader;
	
	import flash.utils.Dictionary;
	import flash.utils.ByteArray;
	
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.events.EventDispatcher;
	
	import flash.system.LoaderContext;
	import flash.display.LoaderInfo;
	import flash.display.Loader;
	
	/**
	 *
	 * @link https://hutrasoftutility.googlecode.com/svn
	 * @author hunglx
	 * @version 1.0.0.4 10/24/2011 10:36 PM
	 */
	public class Repareloader extends EventDispatcher {
		
		public static const TEXT:String = "text";
		public static const BINARY:String = "binary";
		public static const VARIABLES:String = "variables";
		
		public static const COMPLETE:String = "complete";
		public static const PROGRESS:String = "progress";
		
		private var bytesLoaded:Number = 0;
		private var bytesTotal:Number = 0;
		
		private var lista:Array = new Array();
		private var listc:Array = new Array();
		private var listb:Array = new Array();
		private var listd:Dictionary = new Dictionary();
		
		public var data:Array = new Array();
		
		public function Repareloader(provide:Array = null) {
			if (provide != null)
				data = provide;
		}
		
		public function addTarget(url:String, type:String, key:String):void {
			var multirequest:URILoader = new URILoader();
			multirequest.addEventListener(Event.COMPLETE, onCompleteData);
			multirequest.addEventListener(ProgressEvent.PROGRESS, onProgress);
			
			multirequest.dataFormat = type;
			multirequest.url = url;
			multirequest.key = key;
			multirequest.id = lista.push(multirequest) - 1;
			listc.push(key);
			listd[key] = new ProgressEvent(ProgressEvent.PROGRESS, false, false, 0, 0);
		}
		
		public function addBytes(bytes:ByteArray, key:String):void {
			try {
				var loader:MRELoader = new MRELoader();
				loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteContent);
				loader.data = bytes;
				loader.key = key;
				loader.id = listb.push(loader) - 1;
			} catch (e:Error) {
			}
		}
		
		public function loadFiles():void {
			try {
				if (lista.length == 0)
					dispatchEvent(new Event(Event.COMPLETE));
				for (var i:int = 0; i < lista.length; i++) {
					lista[i].load(new URLRequest(lista[i].url));
				}
			} catch (e:Error) {
				
			}
		}
		
		public function loadByte():void {
			try {
				if (listb.length == 0)
					dispatchCompleted();
				for (var i:int = 0; i < listb.length; i++) {
					try {
						listb[i].loadBytes(listb[i].data);
					} catch (e:Error) {
						
					}
				}
			} catch (e:Error) {
			}
		}
		
		/**
		 *
		 * public function loadBytesBase(strbase64:String, onCompleted:Function):void
		 * {
		 * 	var loader:MRELoader = new MRELoader();
		 * 		loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onCompleted);
		 * 		loader.loadBytes(Base64.decodeToByteArray(strbase64));
		 * }
		 * @return
		 */
		private function checkMultiDataCompleted():Boolean {
			for (var i:int = 0; i < lista.length; i++) {
				if (lista[i] != null) {
					return false;
				}
			}
			return true;
		}
		
		private function checkMultiContentCompleted():Boolean {
			try {
				for (var i:int = 0; i < listb.length; i++) {
					if (listb[i] != null) {
						return false;
					}
				}
			} catch (e:Error) {
				return false;
			}
			return true;
		}
		
		private function onCompleteContent(e:Event = null):void {
			try {
				var loader:MRELoader = (MRELoader)(e.target.loader);
				//[1]
				data[loader.key] = e.currentTarget.content;
				//[2]	For check is finnished!
				listb[loader.id] = null;
				//[3]
				if (checkMultiContentCompleted()) {
					dispatchCompleted();
				}
			} catch (e:Error) {
			}
		}
		
		private function onProgress(evt:ProgressEvent = null):void {
			listd[evt.target.key] = evt;
			for (var i:int = 0; i < listc.length; i++) {
				bytesLoaded = bytesLoaded + ProgressEvent(listd[listc[i]]).bytesLoaded;
				bytesTotal = bytesTotal + ProgressEvent(listd[listc[i]]).bytesTotal;
			}
			dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, false, false, bytesLoaded, bytesTotal));
			bytesLoaded = 0;
			bytesTotal = 0;
		}
		
		private function onCompleteData(evt:Event = null):void {
			try {
				
				var object:URILoader = evt.target as URILoader;
				
				if (object.dataFormat == TEXT || object.dataFormat == VARIABLES)
					data[object.key] = object.data;
				
				if (object.dataFormat == BINARY)
					addBytes(object.data, object.key);
				
				object.removeEventListener(Event.COMPLETE, onCompleteData);
				lista[object.id] = null;
				
				if (checkMultiDataCompleted()) {
					loadByte();
				}
			} catch (e:Error) {
				
			}
		}
		
		private function dispatchCompleted():void {
			dispatchEvent(new Event(Event.COMPLETE));
		}
	}
}
import flash.net.URLLoader;

class URILoader extends URLLoader {
	public var id:int;
	public var key:String;
	public var url:String;
}
import flash.utils.ByteArray;
import flash.display.Loader;

class MRELoader extends Loader {
	public var id:int;
	public var key:String;
	public var data:ByteArray;
}